﻿using System;
using System.Collections.Generic;
using System.Text; 
using T.FAS.Runtime.Metadata.Entity;
using T.ServiceComponent.DataAccessEx.Core;
using T.ServiceComponent.Error;
using T.ServiceComponent.Monitor.Client;
using T.ServiceComponent.Runtime.Common;
using System.Transactions;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.Base.Entity;
using System.Text.RegularExpressions;

namespace T.FAS.Runtime.DataModel.Plugin
{
    /// <summary>
    /// SQL item执行器
    /// </summary>
    public class SQLExcutor
    {
        /// <summary>
        /// 通过配置中心获取数据库服务
        /// </summary>
        /// <param name="configkey">配置key</param>
        /// <returns>数据库服务</returns>
        private static ITDatabase GetDatabaseByConfigkey(string configkey)
        {
            try
            {
                return DatabaseHelper.GetDatabaseByConnectionKey(configkey);
            }
            catch (Exception e)
            {
                throw new FasException(DataModelErrorCode.DO.SyncGetDBError, $"配置串:{configkey}生成DB访问实例失败", e);
            }
        }

        /// <summary>
        /// 执行SQL
        /// </summary>
        /// <param name="items"></param>
        public static void ExcuteSQL(SQLItem item)
        {
            var db = GetDatabaseByConfigkey(item.ConfigKey);
            if (db == null)
                throw new FasException(DataModelErrorCode.DO.SyncGetDBError, $"配置项:{item.ConfigKey}获取DB实例失败!");
            #region 日志打印
            StringBuilder sb = new StringBuilder();
            var paras = item.Parameters;
            
            if (paras != null && paras.Count > 0)
            {
                foreach (var para in paras)
                {
                    if (para == null)
                        continue;
                    sb.AppendLine($"ParaName:{para.ParameterName}, ParaValue:{para.Value?.ToString()}");
                }
            }
            #endregion
            if (item.SQLType == SQLType.DML)    //DML执行时使用参数变量替换方式
                db.ExecSqlStatement(item.SQL, item.Parameters.ToArray());
            else
                db.ExecSqlStatement(item.SQL);
        }

        /// <summary>
        /// 批量执行SQL
        /// </summary>
        /// <param name="items"></param>
        public static void ExcuteSQLs(List<SQLItem> items)
        {

            //debug调试，批量打印sql
            StringBuilder log = new StringBuilder();
            foreach (var item in items)
            {
                log.Append(item.SQL);
            }
            string BatchExcuteSQLs = log.ToString();
            //LocalLogService.WriteSQL($"批量打印DO一键调测SQL===>\r\n" + BatchExcuteSQLs);

            foreach (var item in items)
            {
                try
                {
                    ExcuteSQL(item);
                }
                catch (Exception e)
                {
                    var sql = item.SQL;
                    try
                    {
                        string pattern = @"\s+"; // \s 匹配任何空白字符，+ 表示匹配一个或多个
                        string replacement = " "; // 替换为一个空格
                        sql = Regex.Replace(sql, pattern, replacement);
                    }
                    catch
                    {
                    }
                    throw new FasException(DataModelErrorCode.Error, $"元数据类型:{item.MetaDataType},ID:{item.MetaDataID},Code:{item.MetaDataCode},SQL:{sql},执行SQL失败", e);
                }
            }
        }
    }
}